﻿#include "ISEA4HQuery.hpp"
using namespace NNU::DGGS::Base;
using namespace NNU::DGGS::Kernel::ISEA4H;

void ISEA4HQuery::init()
{
	for (int i = 0; i <MaxLevel; i++)
	{
		this->maxRow[i] = (long long int)(pow(2, i));
		this->fMaxCol[i] =  (long long int)(pow(2, i));
		this->eMaxCol[i] = this->fMaxCol[i] * 3;
		this->vMaxCol[i] = this->fMaxCol[i] * 2;
	}
}

ISEA4HQuery::~ISEA4HQuery()
{
    delete[] this->maxRow;
    this->maxRow= nullptr;
    delete[] this->fMaxCol;
    this->fMaxCol= nullptr;
    delete[] this->eMaxCol;
    this->eMaxCol= nullptr;
    delete[] this->vMaxCol;
    this->vMaxCol= nullptr;
}

//是否为中心子节点
bool isInteriorChild(DGGSElementCode code)
{
	if (code.row % 2 == 0 && code.col % 2 == 0)
	{
		return true;
	}
	else
	{
		return false;
	}
}

//获取二十面体大菱形块列表
int* getDiamondList(int basePartition)
{
	if (basePartition == 0)
	{
		int* diamondList = new int[5];
		diamondList[0] = 3;
		diamondList[1] = 4;
		diamondList[2] = 5;
		diamondList[3] = 1;
		diamondList[4] = 2;
		return diamondList;
	}
	else if (basePartition == 11)
	{
		int* diamondList = new int[5];
		diamondList[0] = 10;
		diamondList[1] = 9;
		diamondList[2] = 8;
		diamondList[3] = 7;
		diamondList[4] = 6;
		return diamondList;
	}
	else if (basePartition < 6)
	{
		int* diamondList = new int[4];
		int case2adjTbl[][4] = {
		   {5, 2, 6, 10},  // q == 1
		   {1, 3, 7, 6},   // q == 2
		   {2, 4, 8, 7},   // q == 3
		   {3, 5, 9, 8},   // q == 4
		   {4, 1, 10, 9} }; // q == 5
		diamondList[0] = case2adjTbl[basePartition - 1][0];
		diamondList[1] = case2adjTbl[basePartition - 1][1];
		diamondList[2] = case2adjTbl[basePartition - 1][2];
		diamondList[3] = case2adjTbl[basePartition - 1][3];
		return diamondList;
	}
	else if (basePartition <= 10)
	{
		int* diamondList = new int[4];
		int case2adjTbl[][4] = {
		   {1, 2, 7, 10},  // q == 6
		   {2, 3, 8, 6},   // q == 7
		   {3, 4, 9, 7},   // q == 8
		   {4, 5, 10, 8},  // q == 9
		   {5, 1, 6, 9} };  // q == 10
		diamondList[0] = case2adjTbl[basePartition - 6][0];
		diamondList[1] = case2adjTbl[basePartition - 6][1];
		diamondList[2] = case2adjTbl[basePartition - 6][2];
		diamondList[3] = case2adjTbl[basePartition - 6][3];
		return diamondList;
	}
	else
	{
		return nullptr;
	}
}

//点找面
void ISEA4HQuery::fromVertexSearchRelativeCells(DGGSElementCode code, DGGSElementCode*& results, int& elementNum)
{
	int basePartition = code.basePartition;
	long long int row = code.row;
	long long int col = code.col;
	int* diamondList = getDiamondList(code.basePartition);

    if(code.levelZ == -1)//维度为2
    {
        elementNum = 3;
        results = new DGGSElementCode[elementNum];
    }
    else//维度为3
    {
        //侧面
        int edgesNum=0;
        DGGSElementCode *edges;
        this->fromVertexGetAssociationBoundary(code,edges,edgesNum);

        elementNum=(edgesNum-2)*3;
        results = new DGGSElementCode[elementNum];
        for (int i = 0; i < edgesNum-2; i++)
        {
            results[i+(edgesNum-2)*2]=edges[i];
            results[i+(edgesNum-2)*2].elementType =DGGSElementType::SideFace;

            results[i+(edgesNum-2)]=results[i+(edgesNum-2)*2];
            results[i+(edgesNum-2)].levelZ+=1;
        }
        delete []edges;
        edges= nullptr;
    }

    for (int i = 0; i < 3; i++)
    {
        results[i].level = code.level;
        results[i].elementType =DGGSElementType::Cell;
        results[i].levelZ=code.levelZ;
    }
	if (basePartition == 0 || basePartition == 11)
	{
		if (basePartition == 0)
		{
			results[0].basePartition = diamondList[col];
			results[0].row = 0;
			results[0].col = this->fMaxCol[code.level] - 1;
			if (col == 4)
			{
				results[1].basePartition = diamondList[0];
				results[1].row = 0;
				results[1].col = this->fMaxCol[code.level] - 1;
			}
			else
			{
				results[1].basePartition = diamondList[col + 1];
				results[1].row = 0;
				results[1].col = this->fMaxCol[code.level] - 1;
			}
			results[2].basePartition = 0;
			results[2].row = 0;
			results[2].col = 0;
		}
		else
		{
			results[0].basePartition = diamondList[col];
			results[0].row = this->maxRow[code.level] - 1;
			results[0].col = 0;
			if (col == 4)
			{
				results[1].basePartition = diamondList[0];
				results[1].row = this->maxRow[code.level] - 1;
				results[1].col = 0;
			}
			else
			{
				results[1].basePartition = diamondList[col + 1];
				results[1].row = this->maxRow[code.level] - 1;
				results[1].col = 0;
			}
			results[2].basePartition = 11;
			results[2].row = 0;
			results[2].col = 0;
		}
		return;
	}
	if (row == 0 && col == 0)
	{
		if (basePartition < 6)
		{
			results[0].basePartition = diamondList[3];
			results[0].row = 0;
			results[0].col = this->fMaxCol[code.level] - 1;
			results[1].basePartition = diamondList[0];
			results[1].row = this->maxRow[code.level] - 1;
			results[1].col = this->fMaxCol[code.level] - 1;
		}
		else
		{
			results[0].basePartition = diamondList[3];
			results[0].row = this->maxRow[code.level] - 1;
			results[0].col = this->fMaxCol[code.level] - 1;
			results[1].basePartition = diamondList[0];
			results[1].row = this->maxRow[code.level] - 1;
			results[1].col = 0;
		}
		results[2].basePartition = basePartition;
		results[2].row = 0;
		results[2].col = 0;
	}
	else if (row == 0 && col == this->vMaxCol[code.level] - 1)
	{
		if (basePartition < 6)
		{
			results[0].basePartition = diamondList[0];
			results[0].row = 0;
			results[0].col = this->fMaxCol[code.level] - 1;
			results[1].basePartition = 0;
			results[1].row = 0;
			results[1].col = 0;
			results[2].basePartition = basePartition;
			results[2].row = 0;
			results[2].col = this->fMaxCol[code.level] - 1;
		}
		else
		{
			results[0].basePartition = diamondList[0];
			results[0].row = this->maxRow[code.level] - 1;
			results[0].col = this->fMaxCol[code.level] - 1;
			results[1].basePartition = diamondList[0];
			results[1].row = this->maxRow[code.level] - 1;
			results[1].col = this->fMaxCol[code.level] - 2;
			results[2].basePartition = basePartition;
			results[2].row = 0;
			results[2].col = this->fMaxCol[code.level] - 1;
		}

	}
	else if (row == this->maxRow[code.level] - 1 && col == this->vMaxCol[code.level] - 1)
	{
		results[0].basePartition = basePartition;
		results[0].row = this->maxRow[code.level] - 1;
		results[0].col = this->fMaxCol[code.level] - 1;
		results[1].basePartition = basePartition;
		results[1].row = this->maxRow[code.level] - 2;
		results[1].col = this->fMaxCol[code.level] - 1;
		results[2].basePartition = basePartition;
		results[2].row = this->maxRow[code.level] - 2;
		results[2].col = this->fMaxCol[code.level] - 2;
	}
	else if (row == this->maxRow[code.level] - 1 && col == 0)
	{
		if (basePartition < 6)
		{

			results[0].basePartition = diamondList[3];
			results[0].row = this->maxRow[code.level] - 1;
			results[0].col = this->fMaxCol[code.level] - 1;
			results[1].basePartition = diamondList[3];
			results[1].row = this->maxRow[code.level] - 2;
			results[1].col = this->fMaxCol[code.level] - 1;
			results[2].basePartition = basePartition;
			results[2].row = this->maxRow[code.level] - 1;
			results[2].col = 0;
		}
		else
		{
			results[0].basePartition = diamondList[3];
			results[0].row = this->maxRow[code.level] - 1;
			results[0].col = 0;
			results[1].basePartition = diamondList[3];
			results[1].row = this->maxRow[code.level] - 1;
			results[1].col = 1;
			results[2].basePartition = basePartition;
			results[2].row = this->maxRow[code.level] - 1;
			results[2].col = 0;
		}
	}
	else if (row == 0)
	{
		if (basePartition < 6)
		{
			if (col % 2 == 0)
			{
				results[0].basePartition = diamondList[0];
				results[0].row = this->maxRow[code.level] - col / 2;
				results[0].col = this->fMaxCol[code.level] - 1;
				results[1].basePartition = diamondList[0];
				results[1].row = this->maxRow[code.level] - col / 2 - 1;
				results[1].col = this->fMaxCol[code.level] - 1;
				results[2].basePartition = basePartition;
				results[2].row = row;
				results[2].col = col - 1;
			}
			else
			{
				results[0].basePartition = diamondList[0];
				results[0].row = this->maxRow[code.level] - (col - 1) / 2 - 1;
				results[0].col = this->fMaxCol[code.level] - 1;
				results[1].basePartition = basePartition;
				results[1].row = row;
				results[1].col = (col + 1) / 2 - 1;
				results[2].basePartition = basePartition;
				results[2].row = row;
				results[2].col = (col + 1) / 2;
			}
		}
		else
		{
			if (col % 2 == 0)
			{
				results[0].basePartition = diamondList[0];
				results[0].row = this->maxRow[code.level] - 1;
				results[0].col = col / 2 - 1;
				results[1].basePartition = diamondList[0];
				results[1].row = this->maxRow[code.level] - 1;
				results[1].col = col / 2;
				results[2].basePartition = basePartition;
				results[2].row = row;
				results[2].col = col / 2;
			}
			else
			{
				results[0].basePartition = diamondList[0];
				results[0].row = this->maxRow[code.level] - 1;
				results[0].col = (col - 1) / 2;
				results[1].basePartition = basePartition;
				results[1].row = 0;
				results[1].col = (col + 1) / 2 + 1;
				results[2].basePartition = basePartition;
				results[2].row = row;
				results[2].col = (col + 1) / 2;
			}
		}
	}
	else if (col == this->vMaxCol[code.level] - 1)
	{
		results[0].basePartition = basePartition;
		results[0].row = row;
		results[0].col = this->fMaxCol[code.level] - 1;
		results[1].basePartition = basePartition;
		results[1].row = row - 1;
		results[1].col = this->fMaxCol[code.level] - 1;
		results[2].basePartition = diamondList[1];
		if (basePartition < 6)
		{
			results[2].row = 0;
			results[2].col = this->fMaxCol[code.level] - row;
		}
		else
		{
			results[2].row = row;
			results[2].col = 0;
		}
	}
	else if (col == 0 || col == 1)
	{
		if (basePartition < 6)
		{
			results[0].basePartition = diamondList[3];
			results[0].row = row - 1;
			results[0].col = this->fMaxCol[code.level] - 1;
			if (col == 0)
			{
				results[1].basePartition = diamondList[3];
				results[1].row = row;
				results[1].col = this->fMaxCol[code.level] - 1;
				results[2].basePartition = basePartition;
				results[2].row = row;
				results[2].col = 0;
			}
			else
			{
				results[1].basePartition = basePartition;
				results[1].row = row - 1;
				results[1].col = 0;
				results[2].basePartition = basePartition;
				results[2].row = row;
				results[2].col = 0;
			}
		}
		else
		{
			results[0].basePartition = diamondList[3];
			results[0].row = this->maxRow[code.level] - 1;
			results[0].col = this->fMaxCol[code.level] - row;
			if (col == 0)
			{
				results[1].basePartition = diamondList[3];
				results[1].row = this->maxRow[code.level] - 1;
				results[1].col = this->fMaxCol[code.level] - row - 1;
				results[2].basePartition = basePartition;
				results[2].row = row;
				results[2].col = 0;
			}
			else
			{
				results[1].basePartition = basePartition;
				results[1].row = row - 1;
				results[1].col = 0;
				results[2].basePartition = basePartition;
				results[2].row = row;
				results[2].col = 0;
			}
		}
	}
	else
	{
		if (col % 2 == 0)
		{
			results[0].basePartition = basePartition;
			results[0].row = row - 1;
			results[0].col = col / 2 - 1;
			results[1].basePartition = basePartition;
			results[1].row = row;
			results[1].col = col / 2;
			results[2].basePartition = basePartition;
			results[2].row = row;
			results[2].col = col / 2 - 1;
		}
		else
		{
			results[0].basePartition = basePartition;
			results[0].row = row - 1;
			results[0].col = (col - 1) / 2 - 1;
			results[1].basePartition = basePartition;
			results[1].row = row - 1;
			results[1].col = (col - 1) / 2;
			results[2].basePartition = basePartition;
			results[2].row = row;
			results[2].col = (col - 1) / 2;
		}
	}
	delete []diamondList;
}
//点找边
void ISEA4HQuery::fromVertexGetAssociationBoundary(DGGSElementCode code, DGGSElementCode*& results, int& elementNum)
{

	int basePartition = code.basePartition;
	long long int row = code.row;
	long long int col = code.col;
	int* diamondList = getDiamondList(code.basePartition);

    if(code.levelZ == -1)//维度
    {
        elementNum=3;
        results = new DGGSElementCode[elementNum];
    }
    else
    {
        elementNum=3+2;
        results = new DGGSElementCode[elementNum];
        results[elementNum-2]=code;
        results[elementNum-2].elementType=DGGSElementType::SideEdge;
        results[elementNum-1]=results[elementNum-2];
        results[elementNum-1].levelZ+=1;
    }

    for (int i = 0; i < 3; i++)
    {
        results[i].level = code.level;
        results[i].elementType = DGGSElementType::Edge;
        results[i].levelZ=code.levelZ;
    }
	if (basePartition == 0 || basePartition == 11)
	{
		results[0].basePartition = basePartition;
		results[0].row = 0;
		results[0].col = col;
		if (col == 4)
		{
			results[2].basePartition = basePartition;
			results[2].row = 0;
			results[2].col = 0;
		}
		else
		{
			results[2].basePartition = basePartition;
			results[2].row = 0;
			results[2].col = col + 1;
		}
		if (basePartition == 0)
		{
			if (col < 3)
			{
				results[1].basePartition = int(col) + 3;
				results[1].row = 0;
				results[1].col = this->eMaxCol[code.level] - 2;
			}
			else
			{
				results[1].basePartition = int(col) - 2;
				results[1].row = 0;
				results[1].col = this->eMaxCol[code.level] - 2;
			}
		}
		else
		{
			results[1].basePartition = 10 - int(col);
			results[1].row = this->maxRow[code.level] - 1;
			results[1].col = 0;
		}
	}
	else if (row == 0 && col == 0)
	{
		if (basePartition < 6)
		{
			results[1].basePartition = diamondList[3];
			results[1].row = 0;
			results[1].col = this->eMaxCol[code.level] - 2;
		}
		else
		{
			results[1].basePartition = diamondList[0];
			results[1].row = this->maxRow[code.level] - 1;
			results[1].col = 0;
		}
		results[0].basePartition = basePartition;
		results[0].row = 0;
		results[0].col = col;
		results[2].basePartition = basePartition;
		results[2].row = 0;
		results[2].col = col + 1;
	}
	else if (row == 0 && col == this->vMaxCol[code.level] - 1)
	{
		results[0].basePartition = basePartition;
		results[0].row = 0;
		results[0].col = this->eMaxCol[code.level] - 3;
		if (basePartition < 6)
		{
			results[1].basePartition = diamondList[0];
			results[1].row = 1;
			results[1].col = this->eMaxCol[code.level] - 1;
		}
		else
		{
			results[1].basePartition = diamondList[0];
			results[1].row = this->maxRow[code.level] - 1;
			results[1].col = this->eMaxCol[code.level] - 3;
		}
		results[2].basePartition = basePartition;
		results[2].row = 0;
		results[2].col = this->eMaxCol[code.level] - 2;
	}
	else if (row == this->maxRow[code.level] - 1 && col == this->vMaxCol[code.level] - 1)
	{
		results[0].basePartition = basePartition;
		results[0].row = this->maxRow[code.level] - 1;
		results[0].col = this->eMaxCol[code.level] - 1;
		results[1].basePartition = basePartition;
		results[1].row = this->maxRow[code.level] - 2;
		results[1].col = this->eMaxCol[code.level] - 3;
		results[2].basePartition = basePartition;
		results[2].row = this->maxRow[code.level] - 1;
		results[2].col = this->eMaxCol[code.level] - 2;
	}
	else if (row == this->maxRow[code.level] - 1 && col == 0)
	{
		results[0].basePartition = basePartition;
		results[0].row = this->maxRow[code.level] - 1;
		results[0].col = 0;
		results[2].basePartition = basePartition;
		results[2].row = this->maxRow[code.level] - 1;
		results[2].col = 1;
		if (basePartition < 6)
		{
			results[1].basePartition = diamondList[3];
			results[1].row = this->maxRow[code.level] - 1;
			results[1].col = this->eMaxCol[code.level] - 1;
		}
		else
		{
			results[1].basePartition = diamondList[3];
			results[1].row = this->maxRow[code.level] - 1;
			results[1].col = 3;
		}
	}
	else if (row == 0)
	{
		if (basePartition < 6)
		{
			if (col % 2 == 0)
			{
				results[0].basePartition = basePartition;
				results[0].row = row;
				results[0].col = (col / 2) * 3;
				results[1].basePartition = diamondList[0];
				results[1].row = this->maxRow[code.level] - col / 2;
				results[1].col = this->eMaxCol[code.level] - 1;
				results[2].basePartition = basePartition;
				results[2].row = row;
				results[2].col = (col / 2) * 3 + 1;
			}
			else
			{
				results[0].basePartition = basePartition;
				results[0].row = row;
				results[0].col = (col - 1) / 2 * 3 + 1;
				results[1].basePartition = basePartition;
				results[1].row = row;
				results[1].col = (col - 1) / 2 * 3 + 2;
				results[2].basePartition = basePartition;
				results[2].row = row;
				results[2].col = (col - 1) / 2 * 3 + 3;
			}
		}
		else
		{
			if (col % 2 == 0)
			{
				results[0].basePartition = basePartition;
				results[0].row = row;
				results[0].col = (col / 2) * 3;
				results[1].basePartition = diamondList[0];
				results[1].row = this->maxRow[code.level]-1;
				results[1].col = (col / 2) * 3;
				results[2].basePartition = basePartition;
				results[2].row = row;
				results[2].col = (col / 2) * 3 + 1;
			}
			else
			{
				results[0].basePartition = basePartition;
				results[0].row = row;
				results[0].col = (col - 1) / 2 * 3 + 1;
				results[1].basePartition = basePartition;
				results[1].row = row;
				results[1].col = (col - 1) / 2 * 3 + 2;
				results[2].basePartition = basePartition;
				results[2].row = row;
				results[2].col = (col - 1) / 2 * 3 + 3;
			}
		}
	}
	else if (col == this->vMaxCol[code.level] - 1)
	{
		results[0].basePartition = basePartition;
		results[0].row = row;
		results[0].col = this->eMaxCol[code.level] - 2;
		if (row == 1)
		{
			results[1].basePartition = basePartition;
			results[1].row = row - 1;
			results[1].col = this->eMaxCol[code.level] - 4;
		}
		else
		{
			results[1].basePartition = basePartition;
			results[1].row = row - 1;
			results[1].col = this->eMaxCol[code.level] - 3;
		}
		results[2].basePartition = basePartition;
		results[2].row = row;
		results[2].col = this->eMaxCol[code.level] - 1;
	}
	else if (col == 0)
	{
		results[1].basePartition = basePartition;
		results[1].row = row;
		results[1].col = 1;
		results[2].basePartition = basePartition;
		results[2].row = row;
		results[2].col = 0;
		if (basePartition < 6)
		{
			results[0].basePartition = diamondList[3];
			results[0].row = row;
			results[0].col = this->eMaxCol[code.level] - 1;
		}
		else
		{
			results[0].basePartition = diamondList[3];
			results[0].row = this->maxRow[code.level] - 1;
			results[0].col = this->eMaxCol[code.level] - row * 3;
		}
	}
	else if (row == this->maxRow[code.level] - 1)
	{
		if (col % 2 == 0)
		{
			results[0].basePartition = basePartition;
			results[0].row = row;
			results[0].col = col / 2 * 3 - 1;
			results[1].basePartition = basePartition;
			results[1].row = row;
			results[1].col = col / 2 * 3;
			results[2].basePartition = basePartition;
			results[2].row = row;
			results[2].col = col / 2 * 3 + 1;
		}
		else
		{
			results[0].basePartition = basePartition;
			results[0].row = row;
			results[0].col = (col - 1) / 2 * 3 + 1;
			results[1].basePartition = basePartition;
			results[1].row = row - 1;
			results[1].col = (col - 1) / 2 * 3;
			results[2].basePartition = basePartition;
			results[2].row = row;
			results[2].col = (col - 1) / 2 * 3 + 2;
		}
	}
	else
	{
		if (col % 2 == 0)
		{
			results[0].basePartition = basePartition;
			results[0].row = row;
			results[0].col = col / 2 * 3 - 1;
			results[1].basePartition = basePartition;
			results[1].row = row;
			results[1].col = col / 2 * 3;
			results[2].basePartition = basePartition;
			results[2].row = row;
			results[2].col = col / 2 * 3 + 1;
		}
		else
		{
			results[0].basePartition = basePartition;
			results[0].row = row;
			results[0].col = col  / 2 * 3 + 1;
			results[1].basePartition = basePartition;
			results[1].row = row - 1;
			if (row == 1)
			{
				results[1].col = col  / 2 * 3-1;
                if(col==1)
                    results[1].col = col  / 2 * 3;
			}
			else
			{
				results[1].col = col/ 2 * 3;
			}
			results[2].basePartition = basePartition;
			results[2].row = row;
			results[2].col = col / 2 * 3 + 2;
		}
	}
    delete[]diamondList;
}
//边找点
void ISEA4HQuery::fromEdgeGetBoundary(DGGSElementCode code, DGGSElementCode*& results, int& elementNum)
{
	int basePartition = code.basePartition;
	long long int row = code.row;
	long long int col = code.col;
	int* diamondList = getDiamondList(code.basePartition);
    elementNum=2;
	results = new DGGSElementCode[elementNum];

    //棱边
    if(code.elementType==DGGSElementType::SideEdge)
    {
        results[0]=code;
        results[0].elementType=DGGSElementType::Vertex;
        results[1]=results[0];
        results[1].levelZ= code.levelZ - 1;
        delete[]diamondList;
        return;
    }
    //一般情况
	for (int i = 0; i < 2; i++)
	{
		results[i].level = code.level;
		results[i].elementType = DGGSElementType::Vertex;
        results[i].levelZ=code.levelZ;
	}
	if (basePartition == 0 || basePartition == 11)
	{
		if (basePartition == 0)
		{
			results[0].basePartition = basePartition;
			results[0].row = 0;
			results[0].col = col;
			if (col == 0)
			{
				results[1].basePartition = 0;
				results[1].row = 0;
				results[1].col = 4;
			}
			else
			{
				results[1].basePartition = 0;
				results[1].row = 0;
				results[1].col = col - 1;
			}
		}
		else
		{
			results[0].basePartition = 11;
			results[0].row = 0;
			results[0].col = col;
			if (col == 0)
			{
				results[1].basePartition = 11;
				results[1].row = 0;
				results[1].col = 4;
			}
			else
			{
				results[1].basePartition = 11;
				results[1].row = 0;
				results[1].col = col - 1;
			}
		}
	}
	else if (row == 0)
	{
		if (col == 0)
		{
			results[0].basePartition = basePartition;
			results[0].row = 0;
			results[0].col = 0;
			results[1].basePartition = basePartition;
			results[1].row = 1;
			results[1].col = 1;
		}
		else
		{
			if (col == this->eMaxCol[code.level] - 2 && basePartition < 6)
			{
				results[0].basePartition = basePartition;
				results[0].row = row;
				results[0].col = this->vMaxCol[code.level] - 2;
				if (basePartition < 3)
				{
					results[1].basePartition = 0;
					results[1].row = 0;
					results[1].col = (long long int)(basePartition) + 2l;
				}
				else
				{
					results[1].basePartition = 0;
					results[1].row = 0;
					results[1].col = (long long int)(basePartition) - 3l;
				}
			}
			else if (col == this->eMaxCol[code.level] - 2)
			{
				results[0].basePartition = basePartition;
				results[0].row = row;
				results[0].col = this->vMaxCol[code.level] - 2;
				results[1].basePartition = diamondList[1];
				results[1].row = 0;
				results[1].col = 0;
			}
			else
			{
				if ((col + 1) % 3 == 0)
				{
					results[0].basePartition = basePartition;
					results[0].row = row;
					results[0].col = (col + 1) / 3 * 2 - 1;
					results[1].basePartition = basePartition;
					results[1].row = row + 1;
					results[1].col = (col + 1) / 3 * 2 + 1;
				}
				else if (col % 3 == 0)
				{
					results[0].basePartition = basePartition;
					results[0].row = row;
					results[0].col = col / 3 * 2 - 1;
					results[1].basePartition = basePartition;
					results[1].row = row;
					results[1].col = col / 3 * 2;
				}
				else
				{
					results[0].basePartition = basePartition;
					results[0].row = row;
					results[0].col = (col - 1) / 3 * 2;
					results[1].basePartition = basePartition;
					results[1].row = row;
					results[1].col = (col - 1) / 3 * 2 + 1;
				}
			}
		}
	}
	else if (col == this->eMaxCol[code.level] - 1)
	{
		results[0].basePartition = basePartition;
		results[0].row = row;
		results[0].col = this->vMaxCol[code.level] - 1;
		if (basePartition < 6)
		{
			results[1].basePartition = diamondList[1];
			results[1].row = 0;
			results[1].col = this->vMaxCol[code.level] - row * 2;
		}
		else
		{
			results[1].basePartition = diamondList[1];
			results[1].row = row;
			results[1].col = 0;
		}
	}
	else if (row == this->maxRow[code.level] - 1)
	{
		if (basePartition < 6)
		{
			if (col % 3 == 0)
			{
				results[0].basePartition = basePartition;
				results[0].row = row;
				results[0].col = 2 * (col / 3);
				results[1].basePartition = diamondList[2];
				results[1].row = 0;
				results[1].col = 2 * (col / 3);
			}
			else if ((col - 1) % 3 == 0)
			{
				results[0].basePartition = basePartition;
				results[0].row = row;
				results[0].col = (col - 1) / 3 * 2;
				results[1].basePartition = basePartition;
				results[1].row = row;
				results[1].col = (col - 1) / 3 * 2 + 1;
			}
			else
			{
				results[0].basePartition = basePartition;
				results[0].row = row;
				results[0].col = (col - 2) / 3 * 2 + 1;
				results[1].basePartition = basePartition;
				results[1].row = row;
				results[1].col = (col - 2) / 3 * 2 + 2;
			}
		}
		else
		{
			if (col % 3 == 0)
			{
				results[0].basePartition = basePartition;
				results[0].row = row;
				results[0].col = 2 * (col / 3);
				if (col == 0)
				{
					results[1].basePartition = 11;
					results[1].row = 0;
					results[1].col = 10l-(long long int)(basePartition);
				}
				else
				{
					results[1].basePartition = diamondList[2];
					results[1].row = this->maxRow[code.level] - (col / 3);
					results[1].col = 0;
				}
			}
			else if ((col - 1) % 3 == 0)
			{
				results[0].basePartition = basePartition;
				results[0].row = row;
				results[0].col = (col - 1) / 3 * 2;
				results[1].basePartition = basePartition;
				results[1].row = row;
				results[1].col = (col - 1) / 3 * 2 + 1;
			}
			else
			{
				results[0].basePartition = basePartition;
				results[0].row = row;
				results[0].col = (col - 2) / 3 * 2 + 1;
				results[1].basePartition = basePartition;
				results[1].row = row;
				results[1].col = (col - 2) / 3 * 2 + 2;
			}
		}
	}
	else
	{
		if (col % 3 == 0)
		{
			results[0].basePartition = basePartition;
			results[0].row = row;
			results[0].col = col / 3 * 2;
			results[1].basePartition = basePartition;
			results[1].row = row + 1;
			results[1].col = col / 3 * 2 + 1;
		}
		else if ((col - 1) % 3 == 0)
		{
			results[0].basePartition = basePartition;
			results[0].row = row;
			results[0].col = (col - 1) / 3 * 2;
			results[1].basePartition = basePartition;
			results[1].row = row;
			results[1].col = (col - 1) / 3 * 2 + 1;
		}
		else
		{
			results[0].basePartition = basePartition;
			results[0].row = row;
			results[0].col = (col - 2) / 3 * 2 + 1;
			results[1].basePartition = basePartition;
			results[1].row = row;
			results[1].col = (col - 2) / 3 * 2 + 2;
		}
	}
	delete[] diamondList;
}
//边找面
void ISEA4HQuery::fromEdgeGetAssociationBoundary(DGGSElementCode code, DGGSElementCode*& results, int& elementNum)
{
	int basePartition = code.basePartition;
	long long int row = code.row;
	long long int col = code.col;
	int* diamondList = getDiamondList(code.basePartition);

    //棱边
    if(code.elementType==DGGSElementType::SideEdge)
    {
        int levelD=code.levelZ;
        DGGSElementCode vertex=code;
        vertex.elementType=DGGSElementType::Vertex;
        vertex.levelZ=-1;

        DGGSElementCode*edges;
        int edgeNum=0;
        this->fromVertexGetAssociationBoundary(vertex,edges,edgeNum);
        elementNum=edgeNum;
        results = new DGGSElementCode[elementNum];

        for(int i=0;i<edgeNum;i++)
        {
            results[i]=edges[i];
            results[i].elementType=DGGSElementType::SideFace;
            results[i].levelZ=levelD;
        }
        delete[]edges;
        delete[]diamondList;
        return;
    }
    else
    {
        if(code.levelZ == -1)
        {
            elementNum=2;
            results=new DGGSElementCode[elementNum];
        }
        else
        {
            elementNum=4;
            results = new DGGSElementCode[elementNum];
            //侧面
            results[elementNum-2]=code;
            results[elementNum-2].elementType=DGGSElementType::SideFace;
            results[elementNum-1]=results[elementNum-2];
            results[elementNum-1].levelZ= code.levelZ + 1;
        }
    }
	for (int i = 0; i < 2; i++)
	{
		results[i].level = code.level;
		results[i].elementType = DGGSElementType::Cell;
        results[i].levelZ=code.levelZ;
	}
	if (basePartition == 0 || basePartition == 11)
	{
		if (basePartition == 0)
		{
			if (col < 5)
			{
				results[0].basePartition = int(col) + 1;
				results[0].row = 0;
				results[0].col = this->fMaxCol[code.level] - 1;
			}
			else
			{
				results[0].basePartition = 1;
				results[0].row = 0;
				results[0].col = this->fMaxCol[code.level] - 1;
			}
			results[1].basePartition = basePartition;
			results[1].row = 0;
			results[1].col = 0;
		}
		else
		{
			results[0].basePartition = 10 - int(col);
			results[0].row = this->maxRow[code.level] - 1;
			results[0].col = 0;
			results[1].basePartition = basePartition;
			results[1].row = 0;
			results[1].col = 0;
		}
	}
	else if (row == 0 && col == 0)
	{
		if (basePartition < 6)
		{
			results[0].basePartition = diamondList[3];
			results[0].row = 0;
			results[0].col = this->fMaxCol[code.level] - 1;
		}
		else
		{
			results[0].basePartition = diamondList[3];
			results[0].row = this->maxRow[code.level] - 1;
			results[0].col = this->fMaxCol[code.level] - 1;
		}
		results[1].basePartition = basePartition;
		results[1].row = 0;
		results[1].col = 0;
	}
	else if (row == 0)
	{
		if (basePartition < 6)
		{
			if ((col - 1) % 3 == 0)
			{
				results[0].basePartition = diamondList[0];
				results[0].row = this->maxRow[code.level] - ((col - 1) / 3) - 1;
				results[0].col = this->fMaxCol[code.level] - 1;
				results[1].basePartition = basePartition;
				results[1].row = 0;
				results[1].col = (col - 1) / 3;
			}
			else if ((col - 2) % 3 == 0)
			{
				results[0].basePartition = basePartition;
				results[0].row = 0;
				results[0].col = (col - 2) / 3;
				results[1].basePartition = basePartition;
				results[1].row = 0;
				results[1].col = (col - 2) / 3 + 1;
			}
			else
			{
				results[0].basePartition = diamondList[0];
				results[0].row = this->maxRow[code.level] - (col / 3);
				results[0].col = this->fMaxCol[code.level] - 1;
				results[1].basePartition = basePartition;
				results[1].row = 0;
				results[1].col = col / 3;
			}
		}
		else
		{
			if ((col - 1) % 3 == 0)
			{
				results[0].basePartition = diamondList[0];
				results[0].row = this->maxRow[code.level] - 1;
				results[0].col = (col - 1) / 3;
				results[1].basePartition = basePartition;
				results[1].row = 0;
				results[1].col = (col - 1) / 3;
			}
			else if ((col - 2) % 3 == 0)
			{
				results[0].basePartition = basePartition;
				results[0].row = 0;
				results[0].col = (col - 2) / 3;
				results[1].basePartition = basePartition;
				results[1].row = 0;
				results[1].col = (col - 2) / 3 + 1;
			}
			else
			{
				results[0].basePartition = diamondList[0];
				results[0].row = this->maxRow[code.level] - 1;
				results[0].col = col / 3 - 1;
				results[1].basePartition = basePartition;
				results[1].row = 0;
				results[1].col = col / 3;
			}
		}
	}
	else if (col == 0 || col == 1)
	{
		if (basePartition < 6)
		{
			if (col == 0)
			{
				results[0].basePartition = diamondList[3];
				results[0].row = row;
				results[0].col = this->fMaxCol[code.level] - 1;
				results[1].basePartition = basePartition;
				results[1].row = row;
				results[1].col = 0;
			}
			else
			{
				results[0].basePartition = diamondList[3];
				results[0].row = row - 1;
				results[0].col = this->fMaxCol[code.level] - 1;
				results[1].basePartition = basePartition;
				results[1].row = row;
				results[1].col = 0;
			}
		}
		else
		{
			if (col == 0)
			{
				results[0].basePartition = diamondList[3];
				results[0].row = this->maxRow[code.level] - 1;
				results[0].col = this->fMaxCol[code.level] - row - 1;
				results[1].basePartition = basePartition;
				results[1].row = row;
				results[1].col = 0;
			}
			else
			{
				results[0].basePartition = diamondList[3];
				results[0].row = this->maxRow[code.level] - 1;
				results[0].col = this->fMaxCol[code.level] - row;
				results[1].basePartition = basePartition;
				results[1].row = row;
				results[1].col = 0;
			}
		}
	}
	else
	{
		if ((col - 1) % 3 == 0)
		{
			results[0].basePartition = basePartition;
			results[0].row = row - 1;
			results[0].col = (col - 1) / 3 - 1;
			results[1].basePartition = basePartition;
			results[1].row = row;
			results[1].col = (col - 1) / 3;
		}
		else if ((col - 2) % 3 == 0)
		{
			results[0].basePartition = basePartition;
			results[0].row = row - 1;
			results[0].col = (col - 2) / 3;
			results[1].basePartition = basePartition;
			results[1].row = row;
			results[1].col = (col - 2) / 3;
		}
		else
		{
			results[0].basePartition = basePartition;
			results[0].row = row;
			results[0].col = col / 3 - 1;
			results[1].basePartition = basePartition;
			results[1].row = row;
			results[1].col = col / 3;
		}
	}
	delete[] diamondList;
}
//面找边
void ISEA4HQuery::fromCellGetBoundary(DGGSElementCode code, DGGSElementCode*& results, int& elementNum)
{
    int basePartition = code.basePartition;
    long long int row = code.row;
    long long int col = code.col;
    int* diamondList = getDiamondList(code.basePartition);

    //侧面
    if(code.elementType==DGGSElementType::SideFace)
    {
        elementNum=4;
        results=new DGGSElementCode[elementNum];
        results[0]=code;
        results[0].elementType=DGGSElementType::Edge;
        results[1]=results[0];
        results[1].levelZ= code.levelZ - 1;

        //找棱边
        int vertexNum=0;
        DGGSElementCode* vertex;
        this->fromEdgeGetBoundary(results[0],vertex,vertexNum);
        results[2]=vertex[0];
        results[2].elementType=DGGSElementType::SideEdge;
        results[2].levelZ=code.levelZ;
        results[3]=vertex[1];
        results[3].elementType=DGGSElementType::SideEdge;
        results[3].levelZ=code.levelZ;

        delete[]vertex;
        vertex= nullptr;
        delete[]diamondList;
        return;
    }
    //底面
    if (basePartition == 0 || basePartition == 11)
    {
        elementNum=5;
        results = new DGGSElementCode[elementNum];
        for (int i = 0; i < elementNum; i++)
        {
            results[i].level = code.level;
            results[i].elementType = DGGSElementType::Edge;
            results[i].levelZ=code.levelZ;
        }
        if (basePartition == 0)
        {
            results[0].basePartition = 0;
            results[0].row = 0;
            results[0].col = 2;
            results[1].basePartition = 0;
            results[1].row = 0;
            results[1].col = 3;
            results[2].basePartition = 0;
            results[2].row = 0;
            results[2].col = 4;
            results[3].basePartition = 0;
            results[3].row = 0;
            results[3].col = 0;
            results[4].basePartition = 0;
            results[4].row = 0;
            results[4].col = 1;
        }
        else
        {
            results[0].basePartition = 11;
            results[0].row = 0;
            results[0].col = 2;
            results[1].basePartition = 11;
            results[1].row = 0;
            results[1].col = 3;
            results[2].basePartition = 11;
            results[2].row = 0;
            results[2].col = 4;
            results[3].basePartition = 11;
            results[3].row = 0;
            results[3].col = 0;
            results[4].basePartition = 11;
            results[4].row = 0;
            results[4].col = 1;
        }
    }
    else if (row == 0 && col == 0)
    {
        elementNum=5;
        results = new DGGSElementCode[elementNum];
        for (int i = 0; i < elementNum; i++)
        {
            results[i].level = code.level;
            results[i].elementType = DGGSElementType::Edge;
            results[i].levelZ=code.levelZ;
        }
        results[0].basePartition = basePartition;
        results[0].row = 0;
        results[0].col = 0;
        results[1].basePartition = basePartition;
        results[1].row = 0;
        results[1].col = 1;
        results[2].basePartition = basePartition;
        results[2].row = 0;
        results[2].col = 2;
        results[3].basePartition = basePartition;
        results[3].row = 1;
        results[3].col = 4;
        results[4].basePartition = basePartition;
        results[4].row = 1;
        results[4].col = 2;
    }
    else
    {
        elementNum=6;
        results = new DGGSElementCode[elementNum];
        for (int i = 0; i < elementNum; i++)
        {
            results[i].level = code.level;
            results[i].elementType = DGGSElementType::Edge;
            results[i].levelZ=code.levelZ;
        }
        if (row == this->maxRow[code.level] - 1)
        {
            if (basePartition < 6)
            {
                if (col == this->fMaxCol[code.level] - 1)
                {
                    results[1].basePartition = basePartition;
                    results[1].row = row;
                    results[1].col = this->eMaxCol[code.level] - 2;
                    results[2].basePartition = basePartition;
                    results[2].row = row;
                    results[2].col = this->eMaxCol[code.level] - 1;

                    results[3].basePartition = diamondList[1];
                    results[3].row = 0;
                    results[3].col = this->eMaxCol[code.level] - row * 3;
                    results[4].basePartition = diamondList[1];
                    results[4].row = 0;
                    results[4].col = this->eMaxCol[code.level] - row * 3 - 2;

                    results[5].basePartition = diamondList[2];
                    results[5].row = 0;
                    results[5].col = this->eMaxCol[code.level] - 2;

                    results[0].basePartition = basePartition;
                    results[0].row = row;
                    results[0].col = this->eMaxCol[code.level] - 3;
                }
                else
                {
                    results[0].basePartition = basePartition;
                    results[0].row = row;
                    results[0].col = col * 3;
                    results[1].basePartition = basePartition;
                    results[1].row = row;
                    results[1].col = col * 3 + 1;
                    results[2].basePartition = basePartition;
                    results[2].row = row;
                    results[2].col = col * 3 + 2;
                    results[3].basePartition = basePartition;
                    results[3].row = row;
                    results[3].col = col * 3 + 3;
                    results[4].basePartition = diamondList[2];
                    results[4].row = 0;
                    results[4].col = (1 + col )* 3;
                    results[5].basePartition = diamondList[2];
                    results[5].row = 0;
                    results[5].col = 1 + col* 3;
                }
            }
            else
            {
                if (col == 0)
                {
                    results[0].basePartition = basePartition;
                    results[0].row = row;
                    results[0].col = col * 3;
                    results[1].basePartition = basePartition;
                    results[1].row = row;
                    results[1].col = col * 3 + 1;
                    results[2].basePartition = basePartition;
                    results[2].row = row;
                    results[2].col = col * 3 + 2;
                    results[3].basePartition = basePartition;
                    results[3].row = row;
                    results[3].col = col * 3 + 3;
                    results[4].basePartition = diamondList[2];
                    results[4].row = this->maxRow[code.level] - 1 - col;
                    results[4].col = 0;
                    results[5].basePartition = 11;
                    results[5].row = 0;
                    results[5].col =10l-(long long int)(basePartition);
                }
                else if (col == this->fMaxCol[code.level] - 1)
                {
                    results[0].basePartition = basePartition;
                    results[0].row = row;
                    results[0].col = col * 3;
                    results[1].basePartition = basePartition;
                    results[1].row = row;
                    results[1].col = col * 3 + 1;
                    results[2].basePartition = basePartition;
                    results[2].row = row;
                    results[2].col = col * 3 + 2;
                    results[3].basePartition = diamondList[1];
                    results[3].row = row;
                    results[3].col = 0;
                    results[5].basePartition = diamondList[2];
                    results[5].row = this->maxRow[code.level]  - col;
                    results[5].col = 1;
                    results[4].basePartition = diamondList[2];
                    results[4].row = this->maxRow[code.level] -1- col;
                    results[4].col = 0;
                }
                else
                {
                    results[0].basePartition = basePartition;
                    results[0].row = row;
                    results[0].col = col * 3;
                    results[1].basePartition = basePartition;
                    results[1].row = row;
                    results[1].col = col * 3 + 1;
                    results[2].basePartition = basePartition;
                    results[2].row = row;
                    results[2].col = col * 3 + 2;
                    results[3].basePartition = basePartition;
                    results[3].row = row;
                    results[3].col = col * 3 + 3;
                    results[5].basePartition = diamondList[2];
                    results[5].row = this->maxRow[code.level]  - col;
                    results[5].col = 1;
                    results[4].basePartition = diamondList[2];
                    results[4].row = this->maxRow[code.level] -1- col;
                    results[4].col = 0;
                }
            }
        }
        else if (col == this->fMaxCol[code.level] - 1)
        {
            if (basePartition < 6)
            {
                if (row == 0)
                {
                    results[0].basePartition = basePartition;
                    results[0].row = row;
                    results[0].col = this->eMaxCol[code.level] - 4;
                    results[1].basePartition = basePartition;
                    results[1].row = row;
                    results[1].col = this->eMaxCol[code.level] - 3;
                    results[2].basePartition = basePartition;
                    results[2].row = row;
                    results[2].col = this->eMaxCol[code.level] - 2;

                    results[3].basePartition = 0;
                    results[3].row = 0;
                    results[3].col = (long long int)(basePartition)-1l;

                    results[4].basePartition = diamondList[1];
                    results[4].row = 0;
                    results[4].col = this->eMaxCol[code.level] - 2;
                    results[5].basePartition = basePartition;
                    results[5].row = row + 1;
                    results[5].col = this->eMaxCol[code.level] - 1;

                }
                else
                {
                    results[0].basePartition = basePartition;
                    results[0].row = row;
                    results[0].col = this->eMaxCol[code.level] - 3;
                    results[1].basePartition = basePartition;
                    results[1].row = row;
                    results[1].col = this->eMaxCol[code.level] - 2;
                    results[2].basePartition = basePartition;
                    results[2].row = row;
                    results[2].col = this->eMaxCol[code.level] - 1;

                    results[3].basePartition = diamondList[1];
                    results[3].row = 0;
                    results[3].col = this->eMaxCol[code.level] - row * 3;
                    results[4].basePartition = diamondList[1];
                    results[4].row = 0;
                    results[4].col = this->eMaxCol[code.level] - row * 3 - 2;

                    results[5].basePartition = basePartition;
                    results[5].row = row + 1;
                    results[5].col = this->eMaxCol[code.level] - 1;

                }
            }
            else
            {
                if (row == 0)
                {
                    results[0].basePartition = basePartition;
                    results[0].row = row;
                    results[0].col = this->eMaxCol[code.level] - 4;
                    results[1].basePartition = basePartition;
                    results[1].row = row;
                    results[1].col = this->eMaxCol[code.level] - 3;
                    results[2].basePartition = basePartition;
                    results[2].row = row;
                    results[2].col = this->eMaxCol[code.level] - 2;
                    results[3].basePartition = diamondList[1];
                    results[3].row = 0;
                    results[3].col = 0;
                    results[4].basePartition = diamondList[1];
                    results[4].row = 1;
                    results[4].col = 1;
                    results[5].basePartition = basePartition;
                    results[5].row = row + 1;
                    results[5].col = this->eMaxCol[code.level] - 1;

                }
                else
                {
                    results[0].basePartition = basePartition;
                    results[0].row = row;
                    results[0].col = this->eMaxCol[code.level] - 3;
                    results[1].basePartition = basePartition;
                    results[1].row = row;
                    results[1].col = this->eMaxCol[code.level] - 2;
                    results[2].basePartition = basePartition;
                    results[2].row = row;
                    results[2].col = this->eMaxCol[code.level] - 1;
                    results[3].basePartition = diamondList[1];
                    results[3].row = row;
                    results[3].col = 0;
                    results[4].basePartition = diamondList[1];
                    results[4].row = row + 1;
                    results[4].col = 1;
                    results[5].basePartition = basePartition;
                    results[5].row = row + 1;
                    results[5].col = this->eMaxCol[code.level] - 1;

                }
            }
        }
        else
        {
            if (row == 0)
            {
                results[0].basePartition = basePartition;
                results[0].row = row;
                results[0].col = col * 3 - 1;
                results[1].basePartition = basePartition;
                results[1].row = row;
                results[1].col = col * 3;
                results[2].basePartition = basePartition;
                results[2].row = row;
                results[2].col = col * 3 + 1;
                results[3].basePartition = basePartition;
                results[3].row = row;
                results[3].col = col * 3 + 2;
            }
            else
            {
                results[0].basePartition = basePartition;
                results[0].row = row;
                results[0].col = col * 3;
                results[1].basePartition = basePartition;
                results[1].row = row;
                results[1].col = col * 3 + 1;
                results[2].basePartition = basePartition;
                results[2].row = row;
                results[2].col = col * 3 + 2;
                results[3].basePartition = basePartition;
                results[3].row = row;
                results[3].col = col * 3 + 3;
            }
            results[4].basePartition = basePartition;
            results[4].row = row + 1;
            results[4].col = (col + 1) * 3 + 1;
            results[5].basePartition = basePartition;
            results[5].row = row + 1;
            results[5].col = (col + 1) * 3 - 1;
        }
    }
    delete[] diamondList;
}
//父节点
void ISEA4HQuery::getVoxelParent(DGGSElementCode code, DGGSElementCode*& results, int& elementNum)
{
    DGGSElementCode cell=code;
    cell.elementType=DGGSElementType::Cell;
    this->getCellParent(cell,results,elementNum);
    for(int i=0;i<elementNum;i++)
    {
        results[i].elementType=DGGSElementType::Voxel;
    }
}

void ISEA4HQuery::getCellParent(DGGSElementCode code, DGGSElementCode*& results,int& elementNum)
{
    long long int row = code.row;
    long long int col = code.col;
    int* diamondList = getDiamondList(code.basePartition);
    elementNum=0;
    //一般情况
    if (isInteriorChild(code))
    {
        elementNum = 1;
        long long int parentRow = row / 2;
        long long int parentCol = col / 2;
        results = new DGGSElementCode[1];
        results[0].elementType = DGGSElementType::Cell;
        results[0].basePartition = code.basePartition;
        results[0].row = parentRow;
        results[0].col = parentCol;
        results[0].level = code.level - 1;
        results[0].levelZ=code.levelZ;
    }
    else
    {
        results=new DGGSElementCode[2];
        int levelD=code.levelZ;
        code.levelZ=-1;
        DGGSElementCode *cells= nullptr;
        int cellsNum;
        this->fromCellGetRelativeCells(code,cells,cellsNum);
        for(int i=0;i<cellsNum;i++)
        {
            DGGSElementCode temp=cells[i];
            if(isInteriorChild(cells[i]))
                results[elementNum++]=cells[i];
        }

        for(int i=0;i<elementNum;i++)
        {
            results[i].levelZ=levelD;
            results[i].row/=2;
            results[i].col/=2;
            results[i].level-=1;
        }
    }

    delete[]diamondList;
}

void ISEA4HQuery::getEdgeParent(DGGSElementCode code, DGGSElementCode *&results,int &elementNum)
{
    elementNum=0;
    int levelD=code.levelZ;
    code.levelZ=-1;

    //边找面（2）
    int cellsNum;
    DGGSElementCode *cells= nullptr;
    this->fromEdgeGetAssociationBoundary(code,cells,cellsNum);
    if(isInteriorChild(cells[0])||isInteriorChild(cells[1]))
    {
        elementNum=1;
        if(isInteriorChild(cells[1]))
            cells[0]=cells[1];
        int edgesNum;
        DGGSElementCode *edges= nullptr;
        this->fromCellGetBoundary(cells[0],edges,edgesNum);
        //找边号
        int position=0;
        for(int i=0;i<edgesNum;i++)
        {
            if(edges[i].row==code.row&&edges[i].col==code.col&&edges[i].basePartition==code.basePartition)
            {
                position=i;
                break;
            }
        }

        delete[]edges;
        edges= nullptr;
        int parentNum;
        DGGSElementCode*parent= nullptr;
        this->getCellParent(cells[0],parent,parentNum);
        this->fromCellGetBoundary(parent[0],edges,elementNum);

        elementNum=1;
        results=new DGGSElementCode[elementNum];
        results[0]=edges[position];
        results[0].levelZ=levelD;

        delete[]edges;
        delete[]parent;
        delete[]cells;
        edges= nullptr;
        parent= nullptr;
        cells= nullptr;
    }
    else
    {
        results=new DGGSElementCode[2];
        int parentNum;
        DGGSElementCode *firCellParent,*secCellParent;
        this->getCellParent(cells[0],firCellParent,parentNum);
        this->getCellParent(cells[1],secCellParent,parentNum);

        DGGSElementCode cellParent;
        for(int i=0;i<parentNum;i++)
        {
            for(int j=0;j<parentNum;j++)
                if(firCellParent[i].row==secCellParent[j].row&&firCellParent[i].col==secCellParent[j].col&&firCellParent[i].basePartition==secCellParent[j].basePartition)
                {
                    cellParent=firCellParent[i];
                    break;
                }
        }

        DGGSElementCode interiorCell={DGGSElementType::Cell, cellParent.levelZ, cellParent.level + 1, cellParent.basePartition, 2 * cellParent.row, 2 * cellParent.col};
        int siblingsNum;
        DGGSElementCode *siblings= nullptr;
        this->fromCellGetRelativeCells(interiorCell,siblings,siblingsNum);

        int edgesNum;
        DGGSElementCode *edges= nullptr;
        this->fromCellGetBoundary(cellParent,edges,edgesNum);

        for(int i=0;i<siblingsNum;i++)
        {
            for(int j=0;j<2;j++)
            {
                if(siblings[i].row==cells[j].row&&siblings[i].col==cells[j].col&&siblings[i].basePartition==cells[j].basePartition)
                {
                    results[elementNum]=edges[i];
                    results[elementNum].levelZ=levelD;
                    elementNum++;
                }
            }
        }
        delete[]firCellParent;
        delete[]secCellParent;
        delete[]cells;
        delete[]siblings;
        delete[]edges;

    }
}

void ISEA4HQuery::getVertexParent(DGGSElementCode code, DGGSElementCode*& results, int& elementNum)
{
    int* diamondList = getDiamondList(code.basePartition);
    if(code.row==0&&code.col==this->vMaxCol[code.level]-2)
    {
        elementNum=1;
        results=new DGGSElementCode[elementNum];
        results[0]=code;
        if(code.basePartition>5)
        {
            results[0].basePartition= diamondList[1];
            results[0].level-=1;
            results[0].row=0;
            results[0].col=0;
        }
        else
        {
            results[0].basePartition= 0;
            results[0].level-=1;
            results[0].row=0;
            results[0].col=code.basePartition-1;
        }
    }
    else if(code.row==0&&code.col%4==2)
    {
        elementNum=1;
        results=new DGGSElementCode[elementNum];
        results[0]=code;
        results[0].level-=1;
        results[0].row=0;
        results[0].col=code.col/2;
    }
    else if(code.row%2==1&&code.col%4==0)
    {
        elementNum=1;
        results=new DGGSElementCode[elementNum];
        results[0]=code;
        results[0].level-=1;
        results[0].row=(code.row+1)/2;
        results[0].col=1+code.col/4*2;
    }
    else if(code.row%2==0&&code.col%4==3)
    {
        elementNum=1;
        results=new DGGSElementCode[elementNum];
        results[0]=code;
        results[0].level-=1;
        results[0].row=code.row/2;
        results[0].col=(code.col+1)/2;
    }
    else
    {
        int vertexesNum;
        DGGSElementCode *vertexes= nullptr;
        this->fromVertexGetRelativeVertexes(code,vertexes,vertexesNum);
        for(int i=0;i<vertexesNum;i++)
            if((vertexes[i].row==0&&vertexes[i].col%4==2)||(vertexes[i].row%2==1&&vertexes[i].col%4==0)||(vertexes[i].row%2==0&&vertexes[i].col%4==3))
                this->getVertexParent(vertexes[i],results,elementNum);
    }
}
//子节点
void ISEA4HQuery::getVoxelChildren(DGGSElementCode code, DGGSElementCode*& results, int& elementNum)
{
    DGGSElementCode cell=code;
    cell.elementType=DGGSElementType::Cell;
    this->getCellChildren(cell,results,elementNum);
    for(int i=0;i<elementNum;i++)
    {
        results[i].elementType=DGGSElementType::Voxel;
    }
}

void ISEA4HQuery::getCellChildren(DGGSElementCode code, DGGSElementCode*& results,int& elementNum)
{
	long long int row = code.row;
	long long int col = code.col;
	long long int interiorChildRow = 2 * row;
	long long int interiorChildCol = 2 * col;
	int cellsNum = 0;
	DGGSElementCode interiorChild={DGGSElementType::Cell,-1,code.level+1,code.basePartition,interiorChildRow,interiorChildCol};

	if (code.row==0&&code.col==0)
		elementNum = 6;
	else
		elementNum = 7;
	results = new DGGSElementCode[elementNum];
	results[0] = interiorChild;

    int cellNum;
    DGGSElementCode *cells= nullptr;
    this->fromCellGetRelativeCells(interiorChild,cells,cellNum);
    for(int i=0;i<cellNum;i++)
        results[i+1]=cells[i];
    delete[]cells;
    cells= nullptr;

    for(int i=0;i<elementNum;i++)
        results[i].levelZ=code.levelZ;
}

void ISEA4HQuery::getEdgeChildren(DGGSElementCode code, DGGSElementCode*& results, int& elementNum)
{
    int position=0;
    int levelD=code.levelZ;
    code.levelZ=-1;
    //边找面
    DGGSElementCode *parentCells= nullptr;
    int parentCellsNum=0;
    this->fromEdgeGetAssociationBoundary(code,parentCells,parentCellsNum);

    DGGSElementCode *edges= nullptr;
    int edgesNum;
    this->fromCellGetBoundary(parentCells[0],edges,edgesNum);
    for(int i=0;i<edgesNum;i++)
    {
        if(edges[i].row==code.row&&edges[i].col==code.col&&edges[i].basePartition==code.basePartition)
        {
            position=i;
            break;
        }
    }

    DGGSElementCode interiorCell={DGGSElementType::Cell, parentCells[0].levelZ, parentCells[0].level + 1, parentCells[0].basePartition, 2 * parentCells[0].row, 2 * parentCells[0].col};
    DGGSElementCode *cells= nullptr;
    int cellNum;
    this->fromCellGetRelativeCells(interiorCell,cells,cellNum);

    this->fromCellGetBoundary(cells[position],results,elementNum);
    for(int i=0;i<elementNum;i++)
        results[i].levelZ=levelD;

    delete[]parentCells;
    parentCells= nullptr;
    delete[]edges;
    edges= nullptr;
    delete[] cells;
    cells= nullptr;
}

void ISEA4HQuery::getVertexChildren(DGGSElementCode code, DGGSElementCode*& results, int& elementNum)
{
    int levelD=code.levelZ;
    code.levelZ=-1;
    elementNum=4;
    results=new DGGSElementCode[elementNum];
    int basePartition = code.basePartition;
    long long int row = code.row;
    long long int col = code.col;
    int* diamondList = getDiamondList(code.basePartition);

    DGGSElementCode interiorVertex=code;
    interiorVertex.level=code.level+1;
    interiorVertex.levelZ=-1;
    if(code.row==0&&code.col==0)
    {
        if(code.basePartition<6)
        {
            interiorVertex=code;
            interiorVertex.basePartition=diamondList[3];
            interiorVertex.level+=1;
            interiorVertex.row=0;
            interiorVertex.col=this->vMaxCol[code.level+1]-2;
        }
        else
        {
            interiorVertex=code;
            interiorVertex.basePartition=diamondList[0];
            interiorVertex.level+=1;
            interiorVertex.row=this->maxRow[code.level+1]-1;
            interiorVertex.col=0;
        }
    }
    else if(code.row==0)
    {
        if(code.col%2==0)
        {
            if(code.basePartition<6)
            {
                interiorVertex.basePartition=diamondList[0];
                interiorVertex.row=this->maxRow[interiorVertex.level]-code.col;
                interiorVertex.col=this->vMaxCol[interiorVertex.level]-1;
            }
            else
            {
                interiorVertex.basePartition=diamondList[0];
                interiorVertex.row=this->maxRow[interiorVertex.level]-1;
                interiorVertex.col=code.col*2;
            }
        }
        else
        {
            interiorVertex.basePartition=code.basePartition;
            interiorVertex.row=code.row;
            interiorVertex.col=code.col*2;
        }
    }
    else if(code.col==0)
    {
        if(code.basePartition<6)
        {
            interiorVertex.basePartition=diamondList[3];
            interiorVertex.row=code.row*2;
            interiorVertex.col=this->eMaxCol[interiorVertex.level]-1;
        }
        else
        {
            interiorVertex.basePartition=diamondList[3];
            interiorVertex.row=this->maxRow[interiorVertex.level]-1;
            interiorVertex.col=this->eMaxCol[interiorVertex.level]-code.row*4;
        }
    }
    else if(code.col==1)
    {
        interiorVertex.basePartition=code.basePartition;
        interiorVertex.row=code.row*2-1;
        interiorVertex.col=0;
    }
    else
    {
        interiorVertex.basePartition=code.basePartition;
        if(code.col%2==0)
        {
            interiorVertex.row=code.row*2;
            interiorVertex.col=code.col*2-1;
        }
        else
        {
            interiorVertex.row=code.row*2-1;
            interiorVertex.col=code.col*2-2;
        }
    }

    results[0]=interiorVertex;

    int vertexesNum;
    DGGSElementCode *vertexes= nullptr;
    this->fromVertexGetRelativeVertexes(interiorVertex,vertexes,vertexesNum);
    for(int i=0;i<vertexesNum;i++)
    {
        results[i+1]=vertexes[i];
    }
    for(int i=0;i<elementNum;i++)
        results[i].levelZ=levelD;
    delete[]vertexes;
    vertexes= nullptr;

    delete[]diamondList;
    diamondList= nullptr;

}

//邻居节点
void ISEA4HQuery::getVoxelSiblings(DGGSElementCode code, DGGSElementCode*& results, int& elementNum)
{
    DGGSElementCode cell=code;
    cell.elementType=DGGSElementType::Cell;
    this->getCellSiblings(cell,results,elementNum);
    for(int i=0;i<elementNum;i++)
    {
        results[i].elementType=DGGSElementType::Voxel;
    }
}

void ISEA4HQuery::getCellSiblings(DGGSElementCode code, DGGSElementCode*& results,int& elementNum)
{
	DGGSElementCode* parents;
	DGGSElementCode* children;
	int n = 0;
	elementNum = 0;
	this->getCellParent(code, parents,n);
	if (isInteriorChild(code))
	{
		if (code.row == 0 && code.col == 0)
			results = new DGGSElementCode[5];
		else
			results = new DGGSElementCode[6];
		this->getCellChildren(parents[0], children,n);
		delete parents;
		parents = nullptr;
		for (int i = 0; i < n; i++)
		{
            if (children[i].row == code.row && children[i].col == code.col)
				continue;
            results[elementNum] = children[i];
            elementNum++;
			}
		}

	else
	{
		results = new DGGSElementCode[12];
		for (int i = 0; i < 2; i++)
		{
			this->getCellChildren(parents[i], children,n);
			for (int j = 0; j < n; j++)
			{
                 if (children[j].row == code.row && children[j].col == code.col)
					continue;
                results[elementNum]= children[j];
                elementNum++;
				}
			}
		}
		delete []parents;
		parents = nullptr;
}

void ISEA4HQuery::getEdgeSiblings(DGGSElementCode code, DGGSElementCode *&results, int &elementNum)
{
    int parentNum;
    DGGSElementCode*parent= nullptr;
    this->getEdgeParent(code,parent,parentNum);

    int firEdgesNum=0;
    DGGSElementCode*firEdges= nullptr;
    this->getEdgeChildren(parent[0],firEdges,firEdgesNum);

    int secEdgesNum=0;
    DGGSElementCode*secEdges= nullptr;
    if(parentNum==2)
    {
        this->getEdgeChildren(parent[1],secEdges,secEdgesNum);
        results=new DGGSElementCode[firEdgesNum+secEdgesNum-2];
    }
    else
        results=new DGGSElementCode[firEdgesNum-1];

    elementNum=0;
    for(int i=0;i<firEdgesNum;i++)
    {
        if(code.row==firEdges[i].row&&code.col==firEdges[i].col&&code.basePartition==firEdges[i].basePartition)
            continue;
        results[elementNum++]=firEdges[i];
    }
    for(int i=0;i<secEdgesNum;i++)
    {
        if(code.row==secEdges[i].row&&code.col==secEdges[i].col&&code.basePartition==secEdges[i].basePartition)
            continue;
        results[elementNum++]=secEdges[i];
    }

    delete[]parent;
    parent= nullptr;
    delete[]firEdges;
    firEdges= nullptr;
    if(secEdges)
    {
        delete[]secEdges;
        secEdges= nullptr;
    }
}

void ISEA4HQuery::getVertexSiblings(DGGSElementCode code, DGGSElementCode *&results, int &elementNum)
{
    int parentNum;
    DGGSElementCode*parent= nullptr;
    this->getVertexParent(code,parent,parentNum);

    int vertexesNum=0;
    DGGSElementCode*vertexes= nullptr;
    this->getVertexChildren(parent[0], vertexes, vertexesNum);


    elementNum=0;
    results=new DGGSElementCode[vertexesNum-1];
    for(int i=0; i < vertexesNum; i++)
    {
        if(code.row == vertexes[i].row && code.col == vertexes[i].col && code.basePartition == vertexes[i].basePartition)
            continue;
        results[elementNum++]=vertexes[i];
    }


    delete[]parent;
    parent= nullptr;
    delete[]vertexes;
    vertexes= nullptr;

}

//面找面
void ISEA4HQuery::fromCellGetRelativeCells(DGGSElementCode code, DGGSElementCode*& results, int& elementNum)
{
	DGGSElementCode* edges = nullptr;
    int edgesNum=0;
	this->fromCellGetBoundary( code, edges,edgesNum);

    if(code.levelZ != -1)//3维
        elementNum=3*edgesNum;
    else
        elementNum=edgesNum;
    results = new DGGSElementCode[elementNum];

    int resultsCount = 0;
	for (int i = 0; i < edgesNum; i++)
	{
		DGGSElementCode* cells;
        int cellsNum=0;
		this->fromEdgeGetAssociationBoundary(edges[i], cells,cellsNum);
		for (int j = 0; j < cellsNum; j++)
		{
			if ((cells[j].basePartition == code.basePartition && cells[j].row == code.row && cells[j].col == code.col
            &&cells[j].elementType==code.elementType))
                continue;
            results[resultsCount++]=cells[j];
		}
		delete []cells;
		cells = nullptr;
	}
    delete[]edges;
	edges = nullptr;
}
//面找点
void ISEA4HQuery::fromCellGetRelativeVertexes(DGGSElementCode code, DGGSElementCode*& results, int& elementNum)
{
	int basePartition = code.basePartition;
	long long int row = code.row;
	long long int col = code.col;
	int* diamondList = getDiamondList(code.basePartition);

	if (basePartition == 0 || basePartition == 11)
	{
        elementNum=5;
        results = new DGGSElementCode[elementNum];
        for (int i = 0; i < elementNum; i++)
        {
            results[i].level = code.level;
            results[i].elementType = DGGSElementType::Vertex;
            results[i].levelZ=code.levelZ;
        }
		if (basePartition == 0)
		{
			results[0].basePartition = 0;
			results[0].row = 0;
			results[0].col = 2;
			results[1].basePartition = 0;
			results[1].row = 0;
			results[1].col = 3;
			results[2].basePartition = 0;
			results[2].row = 0;
			results[2].col = 4;
			results[3].basePartition = 0;
			results[3].row = 0;
			results[3].col = 0;
			results[4].basePartition = 0;
			results[4].row = 0;
			results[4].col = 1;
		}
		else
		{
			results[0].basePartition = 11;
			results[0].row = 0;
			results[0].col = 2;
			results[1].basePartition = 11;
			results[1].row = 0;
			results[1].col = 3;
			results[2].basePartition = 11;
			results[2].row = 0;
			results[2].col = 4;
			results[3].basePartition = 11;
			results[3].row = 0;
			results[3].col = 0;
			results[4].basePartition = 11;
			results[4].row = 0;
			results[4].col = 1;
		}
		return;
	}
	else if (row == 0 && col == 0)
	{
        elementNum=5;
        results = new DGGSElementCode[elementNum];
        for (int i = 0; i < elementNum; i++)
        {
            results[i].level = code.level;
            results[i].elementType = DGGSElementType::Vertex;
            results[i].levelZ=code.levelZ;
        }
		if (basePartition < 6)
		{
			results[0].basePartition = basePartition;
			results[0].row = 1;
			results[0].col = 3;
			results[1].basePartition = basePartition;
			results[1].row = 0;
			results[1].col = 1;
			results[2].basePartition = basePartition;
			results[2].row = 0;
			results[2].col = 0;
			results[3].basePartition = basePartition;
			results[3].row = 1;
			results[3].col = 1;
			results[4].basePartition = basePartition;
			results[4].row = 1;
			results[4].col = 2;

		}
		else
		{
			results[0].basePartition = basePartition;
			results[0].row = 1;
			results[0].col = 3;
			results[1].basePartition = basePartition;
			results[1].row = 0;
			results[1].col = 1;
			results[2].basePartition = basePartition;
			results[2].row = 0;
			results[2].col = 0;
			results[3].basePartition = basePartition;
			results[3].row = 1;
			results[3].col = 1;
			results[4].basePartition = basePartition;
			results[4].row = 1;
			results[4].col = 2;
		}

	}
	else
    {
        elementNum=6;
        results = new DGGSElementCode[elementNum];
        for (int i = 0; i < elementNum; i++)
        {
            results[i].level = code.level;
            results[i].elementType = DGGSElementType::Vertex;
            results[i].levelZ=code.levelZ;
        }
        if (row == this->maxRow[code.level] - 1 && col == this->fMaxCol[code.level] - 1)
        {
            results[2].basePartition = basePartition;
            results[2].row = row;
            results[2].col = this->vMaxCol[code.level] - 1;
            results[3].basePartition = basePartition;
            results[3].row = row;
            results[3].col = this->vMaxCol[code.level] - 2;
            if (basePartition < 6)
            {
                results[1].basePartition = diamondList[1];
                results[1].row = 0;
                results[1].col = 2;
                results[4].basePartition = diamondList[2];
                results[4].row = 0;
                results[4].col = this->vMaxCol[code.level] - 2;
                results[5].basePartition = diamondList[1];
                results[5].row = 0;
                results[5].col = 0;
                results[0].basePartition = diamondList[1];
                results[0].row = 0;
                results[0].col = 1;
            }
            else
            {
                results[0].basePartition = diamondList[2];
                results[0].row = 0;
                results[0].col = 0;
                results[1].basePartition = diamondList[1];
                results[1].row = row;
                results[1].col = 0;
                results[4].basePartition = diamondList[2];
                results[4].row = 1;
                results[4].col = 0;
                results[5].basePartition = diamondList[2];
                results[5].row = 1;
                results[5].col = 1;
            }
        }

        else if (col == this->fMaxCol[code.level] - 1)
        {
            if (row == 0)
            {
                results[2].basePartition = basePartition;
                results[2].row = row;
                results[2].col = this->vMaxCol[code.level] - 2;
                results[3].basePartition = basePartition;
                results[3].row = row;
                results[3].col = this->vMaxCol[code.level] - 3;
            }
            else
            {
                results[2].basePartition = basePartition;
                results[2].row = row;
                results[2].col = this->vMaxCol[code.level] - 1;
                results[3].basePartition = basePartition;
                results[3].row = row;
                results[3].col = this->vMaxCol[code.level] - 2;
            }
            results[4].basePartition = basePartition;
            results[4].row = row + 1;
            results[4].col = this->vMaxCol[code.level] - 1;
            if (basePartition < 6)
            {
                results[5].basePartition = diamondList[1];
                results[5].row = 0;
                results[5].col = this->vMaxCol[code.level] - 2 - (2 * row);
                if (row == 0)
                {
                    if (basePartition == 1)
                    {
                        results[1].basePartition = 0;
                        results[1].row = 0;
                        results[1].col = (long long int)(basePartition) + 2l;
                        results[0].basePartition = 0;
                        results[0].row = 0;
                        results[0].col =  (long long int)(basePartition) + 3l;
                    }
                    else if (basePartition == 2)
                    {
                        results[1].basePartition = 0;
                        results[1].row = 0;
                        results[1].col =  (long long int)(basePartition) + 2l;
                        results[0].basePartition = 0;
                        results[0].row = 0;
                        results[0].col = 0;
                    }
                    else
                    {
                        results[1].basePartition = 0;
                        results[1].row = 0;
                        results[1].col =  (long long int)(basePartition) - 3l;
                        results[0].basePartition = 0;
                        results[0].row = 0;
                        results[0].col =  (long long int)(basePartition) - 2l;
                    }
                }
                else
                {
                    results[0].basePartition = diamondList[1];
                    results[0].row = 0;
                    results[0].col = this->vMaxCol[code.level] - 2 - (2 * row) + 1;
                    results[1].basePartition = diamondList[1];
                    results[1].row = 0;
                    results[1].col = this->vMaxCol[code.level] - 2 - (2 * row) + 2;
                }
            }
            else
            {
                if (row == 0)
                {
                    results[5].basePartition = diamondList[1];
                    results[5].row = 1;
                    results[5].col = 0;
                    results[0].basePartition = diamondList[1];
                    results[0].row = 1;
                    results[0].col = 1;
                    results[1].basePartition = diamondList[1];
                    results[1].row = 0;
                    results[1].col = 0;
                }
                else
                {
                    results[5].basePartition = diamondList[1];
                    results[5].row = row + 1;
                    results[5].col = 0;
                    results[0].basePartition = diamondList[1];
                    results[0].row = row + 1;
                    results[0].col = 1;
                    results[1].basePartition = diamondList[1];
                    results[1].row = row;
                    results[1].col = 0;
                }
            }
        }
        else if (row == this->maxRow[code.level] - 1)
        {
            results[3].basePartition = basePartition;
            results[3].row = row;
            results[3].col = col * 2;
            results[2].basePartition = basePartition;
            results[2].row = row;
            results[2].col = col * 2 + 1;
            results[1].basePartition = basePartition;
            results[1].row = row;
            results[1].col = col * 2 + 2;
            if (basePartition < 6)
            {
                results[4].basePartition = diamondList[2];
                results[4].row = 0;
                results[4].col = col * 2;
                results[5].basePartition = diamondList[2];
                results[5].row = 0;
                results[5].col = col * 2 + 1;
                results[0].basePartition = diamondList[2];
                results[0].row = 0;
                results[0].col = col * 2 + 2;
            }
            else
            {
                if (col == 0)
                {
                    if (basePartition == 10)
                    {
                        results[4].basePartition = 11;
                        results[4].row = 0;
                        results[4].col = 0;
                        results[5].basePartition = 11;
                        results[5].row = 0;
                        results[5].col = 4;
                    }
                    else
                    {
                        results[4].basePartition = 11;
                        results[4].row = 0;
                        results[4].col = 10 - (long long int)(basePartition);
                        results[5].basePartition = 11;
                        results[5].row = 0;
                        results[5].col = 9 - (long long int)(basePartition);
                    }
                    results[0].basePartition = diamondList[2];
                    results[0].row = this->maxRow[code.level] - 1;
                    results[0].col = 0;
                }
                else
                {
                    results[4].basePartition = diamondList[2];
                    results[4].row = this->maxRow[code.level] - col;
                    results[4].col = 0;
                    results[5].basePartition = diamondList[2];
                    results[5].row = this->maxRow[code.level] - col;
                    results[5].col = 1;
                    results[0].basePartition = diamondList[2];
                    results[0].row = this->maxRow[code.level] - col - 1;
                    results[0].col = 0;
                }
            }
        }
        else
        {
            if (row == 0)
            {
                results[1].basePartition = basePartition;
                results[1].row = row;
                results[1].col = col * 2 + 1;
                results[2].basePartition = basePartition;
                results[2].row = row;
                results[2].col = col * 2;
                results[3].basePartition = basePartition;
                results[3].row = row;
                results[3].col = col * 2 - 1;
            }
            else
            {
                results[1].basePartition = basePartition;
                results[1].row = row;
                results[1].col = col * 2 + 2;
                results[2].basePartition = basePartition;
                results[2].row = row;
                results[2].col = col * 2 + 1;
                results[3].basePartition = basePartition;
                results[3].row = row;
                results[3].col = col * 2;
            }
            results[4].basePartition = basePartition;
            results[4].row = row + 1;
            results[4].col = col * 2 + 1;
            results[5].basePartition = basePartition;
            results[5].row = row + 1;
            results[5].col = col * 2 + 2;
            results[0].basePartition = basePartition;
            results[0].row = row + 1;
            results[0].col = col * 2 + 3;
        }
    }
    delete[]diamondList;
}
//点找点
void ISEA4HQuery::fromVertexGetRelativeVertexes(DGGSElementCode code, DGGSElementCode*& results, int& elementNum)
{
    if(code.levelZ == -1)
        elementNum=3;
    else
        elementNum=3+2;
	results = new DGGSElementCode[elementNum];
	int resultsCount = 0;
	DGGSElementCode* edges;
    int edgesNum=0;
	this->fromVertexGetAssociationBoundary( code, edges,edgesNum);
	for (int i = 0; i < edgesNum; i++)
	{
		DGGSElementCode* vertexes;
        int vertexesNum=0;
		this->fromEdgeGetBoundary(edges[i], vertexes,vertexesNum);

        for(int j=0;j<vertexesNum;j++)
        {
            if(code.row==vertexes[j].row&&code.col==vertexes[j].col&&code.basePartition==vertexes[j].basePartition&& code.levelZ == vertexes[j].levelZ
                            &&code.elementType==vertexes[j].elementType)
                continue;
            results[resultsCount++]=vertexes[j];
        }
        delete []vertexes;
        vertexes= nullptr;
	}
	delete []edges;
	edges = NULL;
}
//边找边
void ISEA4HQuery::fromEdgeGetRelativeEdges(DGGSElementCode code, DGGSElementCode*& results, int& elementNum)
{
    if(code.levelZ == -1)
        results = new DGGSElementCode[4];
    else
        results=new DGGSElementCode[8];

    elementNum=0;

	DGGSElementCode* vertexes;
    int vertexNum=0;
	this->fromEdgeGetBoundary( code, vertexes,vertexNum);
	for (int i = 0; i < vertexNum; i++)
	{
		DGGSElementCode* edges;
        int edgesNum=0;
		this->fromVertexGetAssociationBoundary( vertexes[i], edges,edgesNum);
		for (int j = 0; j < edgesNum; j++)
		{
            DGGSElementCode tempEdge=edges[j];
			if ((edges[j].basePartition == code.basePartition && edges[j].row == code.row&& edges[j].col == code.col))
                continue;
            results[elementNum++] = edges[j];
		}
        delete []edges;
        edges= nullptr;
	}
	delete []vertexes;
	vertexes = nullptr;
}

//体找面
void ISEA4HQuery::fromVoxelGetRelativeCells(DGGSElementCode code, DGGSElementCode *&results, int &elementNum)
{
    int edgesNum=0;
    DGGSElementCode*edges= nullptr;

    DGGSElementCode*cell;
    cell=new DGGSElementCode[1];
    cell[0]=code;
    cell[0].elementType=DGGSElementType::Cell;

    this->fromCellGetBoundary(cell[0],edges,edgesNum);
    elementNum=edgesNum+2;
    results=new DGGSElementCode[elementNum];

    results[0]=code;
    results[0].elementType=DGGSElementType::Cell;
    results[1]=results[0];
    results[1].levelZ= code.levelZ - 1;

    for(int i=0;i<edgesNum;i++)
    {
        results[i+2]=edges[i];
        results[i+2].elementType=DGGSElementType::SideFace;
    }
    delete[]cell;
    cell= nullptr;
    delete[]edges;
    edges= nullptr;
}

//体找边
void ISEA4HQuery::fromVoxelGetRelativeEdges(DGGSElementCode code, DGGSElementCode *&results, int &elementNum)
{
    if(code.col==0&&code.row==0)
        elementNum=5*3;
    else
        elementNum=6*3;
    results=new DGGSElementCode[elementNum];

    //上下面
    int cellNum=0;
    DGGSElementCode* cells;
    cells=new DGGSElementCode[2];
    cells[0]=code;
    cells[0].elementType=DGGSElementType::Cell;
    cells[1]=cells[0];
    cells[1].levelZ= code.levelZ - 1;
    for(int i=0;i<2;i++)
    {
        int edgesNum=0;
        DGGSElementCode*edges= nullptr;
        this->fromCellGetBoundary(cells[i],edges,edgesNum);
        for(int j=0;j<edgesNum;j++)
            results[i*edgesNum+j]=edges[j];
        delete []edges;
        edges= nullptr;
    }

    //棱边
    int vertexNum=0;
    DGGSElementCode* vertex;
    this->fromCellGetRelativeVertexes(cells[0],vertex,vertexNum);

    for(int k=0;k<vertexNum;k++)
    {
        results[vertexNum*2+k]=vertex[k];
        results[vertexNum*2+k].elementType=DGGSElementType::SideEdge;
        results[vertexNum*2+k].levelZ=code.levelZ;
    }
    delete []vertex;
    vertex= nullptr;
    delete []cells;
    cells= nullptr;

}

//体找点
void ISEA4HQuery::fromVoxelGetRelativeVertexes(DGGSElementCode code, DGGSElementCode *&results, int &elementNum)
{
    if(code.col==0&&code.row==0)
        elementNum=5*2;
    else
        elementNum=6*2;
    results=new DGGSElementCode[elementNum];

    //上下面
    int cellNum=0;
    DGGSElementCode* cells= nullptr;
    cells=new DGGSElementCode[2];
    cells[0]=code;
    cells[0].elementType=DGGSElementType::Cell;
    cells[1]=cells[0];
    cells[1].levelZ= code.levelZ - 1;

    //面找点
    for(int i=0;i<2;i++)
    {
        int vertexNum=0;
        DGGSElementCode* vertexs= nullptr;
        this->fromCellGetRelativeVertexes(cells[i],vertexs,vertexNum);
        for(int j=0;j<vertexNum;j++)
            results[i*vertexNum+j]=vertexs[j];
        delete []vertexs;
        vertexs= nullptr;
    }
}

//面找体
void ISEA4HQuery::fromCellGetRelativeVoxels(DGGSElementCode code, DGGSElementCode *&results, int &elementNum)
{
    elementNum=2;
    results=new DGGSElementCode[elementNum];
    if(code.elementType==DGGSElementType::Cell)
    {
        results[0]=code;
        results[0].elementType=DGGSElementType::Voxel;
        results[1]=results[0];
        results[1].levelZ= code.levelZ + 1;
    }
    else if(code.elementType==DGGSElementType::SideFace)
    {
        DGGSElementCode*edges;
        edges=new DGGSElementCode[1];
        edges[0]=code;
        edges[0].elementType=DGGSElementType::Edge;
        edges[0].levelZ=-1;

        int cellNum=0;
        DGGSElementCode *cells= nullptr;
        this->fromEdgeGetAssociationBoundary(edges[0],cells,cellNum);

        for(int i=0;i<cellNum;i++)
        {
            results[i]=cells[i];
            results[i].elementType=DGGSElementType::Voxel;
            results[i].levelZ=code.levelZ;
        }
        delete [] edges;
        delete [] cells;
    }

}

//边找体
void ISEA4HQuery::fromEdgeGetRelativeVoxels(DGGSElementCode code, DGGSElementCode *&results, int &elementNum)
{
    if(code.elementType==DGGSElementType::SideEdge)
    {
        DGGSElementCode *vertex;
        vertex=new DGGSElementCode[1];
        vertex[0]=code;
        vertex[0].elementType=DGGSElementType::Vertex;
        vertex[0].levelZ=-1;

        DGGSElementCode * cells= nullptr;
        int cellNum=0;
        this->fromVertexSearchRelativeCells(vertex[0],cells,cellNum);
        elementNum=cellNum;
        results=new DGGSElementCode[elementNum];

        for(int i=0;i<cellNum;i++)
        {
            results[i]=cells[i];
            results[i].elementType=DGGSElementType::Voxel;
            results[i].levelZ=code.levelZ;
        }
        delete[]cells;
        delete[]vertex;
    }
    else if(code.elementType==DGGSElementType::Edge)
    {
        DGGSElementCode * cells;
        int cellNum=0;
        this->fromEdgeGetAssociationBoundary(code,cells,cellNum);
        elementNum=(cellNum-2)*2;
        results=new DGGSElementCode[elementNum];

        for(int i=0;i<cellNum-2;i++)
        {
            results[i]=cells[i];
            results[i].elementType=DGGSElementType::Voxel;

            results[i+cellNum-2]=results[i];
            results[i+cellNum-2].levelZ= code.levelZ + 1;
        }
        delete[]cells;
    }
}

//点找体
void ISEA4HQuery::fromVertexGetRelativeVoxels(DGGSElementCode code, DGGSElementCode *&results, int &elementNum)
{
    int levelD=code.levelZ;
    code.levelZ=-1;

    DGGSElementCode * cells;
    int cellNum=0;
    this->fromVertexSearchRelativeCells(code,cells,cellNum);
    elementNum=cellNum*2;
    results=new DGGSElementCode[elementNum];

    for(int i=0;i<cellNum;i++)
    {
        results[i]=cells[i];
        results[i].elementType=DGGSElementType::Voxel;
        results[i].levelZ=levelD;

        results[i+cellNum]=results[i];
        results[i+cellNum].levelZ= code.levelZ + 1;
    }
    delete[]cells;
    cells= nullptr;
}

//体找体
void ISEA4HQuery::fromVoxelGetRelativeVoxels(DGGSElementCode code, DGGSElementCode *&results, int &elementNum)
{
    DGGSElementCode cell=code;
    cell.levelZ=-1;
    cell.elementType=DGGSElementType::Cell;

    DGGSElementCode *cells;
    int cellNum;
    this->fromCellGetRelativeCells(cell,cells,cellNum);
    elementNum=cellNum+2;
    results=new DGGSElementCode[elementNum];

    for(int i=0;i<cellNum;i++)
    {
        results[i]=cells[i];
        results[i].elementType=DGGSElementType::Voxel;
        results[i].levelZ=code.levelZ;
    }

    results[elementNum-2]=code;
    results[elementNum-2].elementType=DGGSElementType::Voxel;
    results[elementNum-2].levelZ= code.levelZ - 1;

    results[elementNum-1]=code;
    results[elementNum-1].elementType=DGGSElementType::Voxel;
    results[elementNum-1].levelZ= code.levelZ + 1;

    delete[]cells;
    cells= nullptr;
}


